#ifndef DATA_TRAN_SRV_H
#define DATA_TRAN_SRV_H

#include <QtCore>
#include <QtNetwork>

#include "ComDefine.h"

//前置声明
class QTcpServer;
class QTcpSocket;
class CModbusFactory;
class CRTDB;
class CBattStack;
typedef struct _SMdobusTcpReq SMdobusTcpReq;
typedef struct _STcpClient STcpClient;
class QSystemSemaphore;

class CDataTranSrv : public QThread
{
	Q_OBJECT
public:
	CDataTranSrv(QObject *parent, CModbusFactory* pModbusFactory);
	~CDataTranSrv();

public:
	void run();

	void startDataTranSrv();

	void setRTDB(CRTDB* pRTDB, CBattStack* pBattStack);
	void setPort(ushort usPort);
	void setCliIdleTime(int iIdleTime);
	void setModbusAddrOffset(uchar uaModbusAddrOffset);
    void SetProjectMode(int iProjectMode);

	void initAlarmCache();

signals:	
	void addLog(int iLogType, const QString& strLog);
	void notifyPCSStateChanged(quint16 usOldPCSState, quint16 usNewPCSState);
	void tcpCliDisconnectedSgl(int iCliIndex);
    void switchLang();

private:
	void initTcpClientSlots(int iCliIndex);
    //接收从站的请求数据,解析并填充应答数据,回复给从站
	void tcpCliReadDatagram(QTcpSocket* pTcpClient, char* pDataBuf);
    void DoStackData(QTcpSocket* pTcpClient, char* pDataBuf, SMdobusTcpReq& req);
    void DoBankData(QTcpSocket* pTcpClient, char* pDataBuf, SMdobusTcpReq& req);
    void DoEnvData(QTcpSocket* pTcpClient, char* pDataBuf, SMdobusTcpReq& req, int iModbusAddress);
    void DoHoldReg(QTcpSocket* pTcpClient, char* pDataBuf, SMdobusTcpReq& req);
    void DoInputReg(QTcpSocket* pTcpClient, char* pDataBuf, SMdobusTcpReq& req);
	void sendExcepDatagram(QTcpSocket* pTcpClient, char* pDataBuf, SMdobusTcpReq* pReq, uchar uaExcepCode);

	void printSendInfo(const QString& strCliIP, char* pBufData, int iLen);
	void printReceInfo(const QString& strCliIP, char* pBufData, int iLen);

	void calculateState(quint16& usStackState, quint16 usNewBattState);

	void checkClientIdle();
	QString getStateDescrip(quint16 usOldState, quint16 usCurState);
	QString getStackState(quint16 usState);

	bool checkRunState(quint16 usOldState, quint16 usCurState);
	void log2DB(int iLogType, const QDateTime& dtStart, quint16 usVal1, quint16 usVal2);

	void processEmerStop();
    //计算支路
	void calculateBranch(const QDateTime& dtStart);

	// Sql 
	void processSql();
	void checkEMSLink();

    void Init();
    void InitMembers();
    void InitTcpClients();
    void InitConnect();
    int GetBranNo(int iBankIndex);

private slots:
	void newTcpConn();

    void tcpCli1Disconnected();
    void tcpCli2Disconnected();
    void tcpCli3Disconnected();
    void tcpCli4Disconnected();
    void tcpCli5Disconnected();
    void tcpCli6Disconnected();
    void tcpCli7Disconnected();
    void tcpCli8Disconnected();
    void tcpCli9Disconnected();
    void tcpCli10Disconnected();
    void tcpCli11Disconnected();
    void tcpCli12Disconnected();
    void tcpCli13Disconnected();
    void tcpCli14Disconnected();
    void tcpCli15Disconnected();
    void tcpCli16Disconnected();
    void tcpCli17Disconnected();
	
	void tcpCli1Error(QAbstractSocket::SocketError socketError);
	void tcpCli2Error(QAbstractSocket::SocketError socketError);
	void tcpCli3Error(QAbstractSocket::SocketError socketError);
	void tcpCli4Error(QAbstractSocket::SocketError socketError);
	void tcpCli5Error(QAbstractSocket::SocketError socketError);
	void tcpCli6Error(QAbstractSocket::SocketError socketError);
	void tcpCli7Error(QAbstractSocket::SocketError socketError);
	void tcpCli8Error(QAbstractSocket::SocketError socketError);
	void tcpCli9Error(QAbstractSocket::SocketError socketError);
	void tcpCli10Error(QAbstractSocket::SocketError socketError);
	void tcpCli11Error(QAbstractSocket::SocketError socketError);
	void tcpCli12Error(QAbstractSocket::SocketError socketError);
	void tcpCli13Error(QAbstractSocket::SocketError socketError);
	void tcpCli14Error(QAbstractSocket::SocketError socketError);
	void tcpCli15Error(QAbstractSocket::SocketError socketError);
	void tcpCli16Error(QAbstractSocket::SocketError socketError);
    void tcpCli17Error(QAbstractSocket::SocketError socketError);

    void TcpClientError(QAbstractSocket::SocketError socketError, STcpClient* pTcpClient);

	void tcpCli1ReadDatagram();
	void tcpCli2ReadDatagram();
	void tcpCli3ReadDatagram();
	void tcpCli4ReadDatagram();
	void tcpCli5ReadDatagram();
	void tcpCli6ReadDatagram();
	void tcpCli7ReadDatagram();
	void tcpCli8ReadDatagram();
	void tcpCli9ReadDatagram();
	void tcpCli10ReadDatagram();
	void tcpCli11ReadDatagram();
	void tcpCli12ReadDatagram();
	void tcpCli13ReadDatagram();
	void tcpCli14ReadDatagram();
	void tcpCli15ReadDatagram();
	void tcpCli16ReadDatagram();
	void tcpCli17ReadDatagram();
	
	void tcpCliDisconnectedSlot(int iCliIndex);

private:
    ushort              m_usPort;
    int                 m_iIdleTime;
    uchar               m_uaModbusAddrOffset; // 地址偏移量
    // #项目模式,默认为0
    // #0,通用项目
    // #1,富仁项目--给第三方EMS提供液冷数据,动环测量(Modbus地址从101,输入寄存器,功能码0x04,共13个UINT16数据,寄存器地址为201~213)
    // #2,海得项目
    // #--提供电表,动环测量(Modbus地址从101,输入寄存器,功能码0x04,共32个FLOAT数据,寄存器地址为201~264)
    // #--提供液冷,动环测量(Modbus地址从101,输入寄存器,功能码0x04,共4个UINT16数据,寄存器地址为301~304)
    // #--提供液冷,动环测量(Modbus地址从101,输入寄存器,功能码0x04,共8个FLOAT数据,寄存器地址为311~326)
    // #--提供PCS的UNIT16数据(Modbus地址从200,输入寄存器,功能码0x04,共9个UINT16数据,寄存器地址为0,2~9,没有1)
    // #--提供PCS的FLOAT数据(Modbus地址从200,输入寄存器,功能码0x04,共25个FLOAT数据,寄存器地址为51~99)
    // #--提供PCS的BIT数据(Modbus地址从200,离散寄存器,功能码0x02,共4个数据,寄存器地址为1~4)
    int                 m_iProjectMode; //项目模式

    CRTDB*              m_pRTDB;
    CBattStack*         m_pBattStack;
    CModbusFactory*     m_pModbusFactory;
    QTcpServer*         m_pTcpServer;
    QList<STcpClient*>* m_plstTcpClient;   // Tcp client
    QStringList         m_lstSql;
    QSystemSemaphore* m_pAlmCacheSem[MAX_BANK_NUM]; //告警缓冲信号量
    QDateTime           m_dtLastChgDropPower;       // 上次充电降功率时间
    QDateTime           m_dtLastDhgDropPower;       // 上次放电降功率时间
    int                 m_iCheckEMSLinkCount;             // EMS 链接检查,1分钟无链接报通讯故障
    int                 m_iOrgLang;
};

#endif // DATA_TRAN_SRV_H
